`
https://leetcode.cn/problems/contiguous-array/
`

/**
 * @param {number[]} nums
 * @return {number}
 */
var findMaxLength = function (nums) {
  const n = nums.length

  // 计算前缀和
  const prefix = new Array(n + 1)
  prefix[0] = 0
  for (let i = 1; i < n + 1; i++) {
    // 把 0 看成 -1 ，将问题等价于找到和为 0 的最长连续子数组
    prefix[i] = prefix[i - 1] + (nums[i - 1] === 0 ? -1 : 1)
  }

  let res = 0

  // 哈希表存储前缀和对应的索引
  const valToIdx = new Map()
  for (let i = 0; i < prefix.length; i++) {
    // 如果没有存储过该前缀和，说明在这之前没有符合条件的子数组
    if (!valToIdx.has(prefix[i])) {
      valToIdx.set(prefix[i], i)
    }
    // 如果之前存储过该前缀和，现在又遇到了一次相同的前缀和
    // 说明这两个前缀和的索引的区间就是符合条件的子数组
    // 需要更新结果
    else {
      res = Math.max(res, i - valToIdx.get(prefix[i]))
    }
  }

  return res
};